import { SetupContext, defineComponent, inject, onMounted, ref } from 'vue';
import { DialProps ,dialProps} from '../dial.props';
import { DesignerItemContext } from '../../../designer-canvas/src/types';
import { useDesignerRules } from './use-designer-rules';
import { useDesignerComponent } from '../../../designer-canvas/src/composition/function/use-designer-component';
import '../dial.scss';

export default defineComponent({
    name: 'FDialDesign',
    props: dialProps,
    setup(props: DialProps, context: SetupContext) {
        const elementRef = ref();
        const designItemContext = inject<DesignerItemContext>('design-item-context') as DesignerItemContext;
        const designerRulesComposition = useDesignerRules(designItemContext.schema, designItemContext.parent?.schema);
        const componentInstance = useDesignerComponent(elementRef, designItemContext, designerRulesComposition);

        const modelValue = ref(props.modelValue);
        const min = ref(props.min);
        const max = ref(props.max);
        const valueTemplate = ref(props.valueTemplate);
        const fontColor = ref(props.fontColor);
        const strokeWidth = ref(props.strokeWidth);
        const size = ref(props.size);
        const valueColor = ref(props.valueColor);
        const rangeColor = ref(props.rangeColor);

        const MathPI = 3.14159265358979;
        const radius = 40;
        const midX = 50;
        const midY = 50;
        const minRadians = (4 * MathPI) / 3;
        const maxRadians = -MathPI / 3;

        onMounted(() => {
            elementRef.value.componentInstance = componentInstance;
        });
        context.expose(componentInstance.value);

        function mapRange(x: number, inMin: number, inMax: number, outMin: number, outMax: number) {
            return ((x - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
        };

        const valueToDisplay = () => {
            return valueTemplate.value.replace(/{value}/g, modelValue.value);
        };

        const minX = () => {
            return midX + Math.cos(minRadians) * radius;
        };

        const minY = () => {
            return midY - Math.sin(minRadians) * radius;
        };

        const maxX = () => {
            return midX + Math.cos(maxRadians) * radius;
        };

        const maxY = () => {
            return midY - Math.sin(maxRadians) * radius;
        };

        const zeroRadians = () => {
            if (min.value > 0 && max.value > 0) {
                return mapRange(min.value, min.value, max.value, minRadians, maxRadians);
            }
            return mapRange(0, min.value, max.value, minRadians, maxRadians);

        };

        const valueRadians = () => {
            return mapRange(modelValue.value, min.value, max.value, minRadians, maxRadians);
        };

        const zeroX = () => {
            return midX + Math.cos(zeroRadians()) * radius;
        };
        const zeroY = () => {
            return midY - Math.sin(zeroRadians()) * radius;
        };
        const valueX = () => {
            return midX + Math.cos(valueRadians()) * radius;
        };
        const valueY = () => {
            return midY - Math.sin(valueRadians()) * radius;
        };

        const largeArc = () => {
            return Math.abs(zeroRadians() - valueRadians()) < MathPI ? 0 : 1;
        };

        const sweep = () => {
            return valueRadians() > zeroRadians() ? 0 : 1;
        };

        const rangePath = () => {
            return `M ${minX()} ${minY()} A ${radius} ${radius} 0 1 1 ${maxX()} ${maxY()}`;
        };

        const valuePath = () => {
            return `M ${zeroX()} ${zeroY()} A ${radius} ${radius} 0 ${largeArc()} ${sweep()} ${valueX()} ${valueY()}`;
        };

        return () => {
            return <div ref={elementRef} class='drag-container' dragref={`${designItemContext.schema.id}-container`}>
                <div class='f-dial'>
                    <svg viewBox="0 0 100 100" width={size.value} height={size.value}>
                        <path d={rangePath()}
                            stroke-width={strokeWidth.value} stroke={valueColor.value} class="f-dial-range"></path>
                        <path d={valuePath()}
                            stroke-width={strokeWidth.value} stroke={rangeColor.value} class="f-dial-value"></path>
                        <text x="50" y="57" text-anchor="middle" fill={fontColor.value} class="f-dial-text">{valueToDisplay()}</text>
                    </svg>
                </div>
            </div>;
        };
    }
});